﻿using Dapper_Console.Common.Infrastructure;
using Dapper_Console.IRepository;
using Dapper_Console.IServices;
using Dapper_Console.Models.Model;
using Dapper_Console.Repository;
using Dapper_Console.Services;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Unity;

namespace Dapper_Console
{
    class Program
    {
      

        /// <summary>
        /// 将Main 改成异步
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static async Task Main(string[] args)
        {
            #region //这里模拟主从读写 没有弄数据库分布了
            Database.MASTER_LOCAL_CONNECTION = ConfigurationManager.AppSettings["MasterDbConnection"].ToString();
            /* Configuration.GetConnectionString("MasterDbConnection"); */
            Database.SLAVE_LOCAL_CONNECTION = ConfigurationManager.AppSettings["SlaveDbConnection"].ToString();
            /* Configuration.GetConnectionString("SlaveDbConnection");  */

            #endregion

            #region IOC   当个 对象的注册
            //创建容器
            UnityContainer container = new UnityContainer();
            //注册依赖对象
            container.RegisterType<ILoginInfoServices, LoginInfoServices>();
            container.RegisterType<ILoginInfoRepository, LoginInfoRepository>();
            container.AddExtension(new Diagnostic());
            ////返回调用者
            ILoginInfoServices ILogin = container.Resolve<LoginInfoServices>();
            #endregion

            #region  多个对象的注册  Untiy +反射 +解耦
            //     string basePath = AppDomain.CurrentDomain.BaseDirectory;
            //     var servicesDllFile = Path.Combine(basePath, "Dapper_Console.Services.dll");//获取注入项目绝对路径 
            //     var assemblysServices = Assembly.LoadFrom(servicesDllFile);//直接采用加载文件的方法 
            ///*     Assembly assemblysServices = Assembly.LoadFrom()*/;
            //     Dictionary<string, Type> dictInterface = new Dictionary<string, Type>();
            //     Dictionary<string, Type> dictDAL = new Dictionary<string, Type>();
            //     string dalSuffix = ".Services";

            #endregion
            #region
            //foreach (Type objType3 in assemblysServices.GetTypes())
            //{
            //    string defaultNamespace = objType3.Namespace;
            //    if (defaultNamespace.EndsWith(dalSuffix))
            //    {
            //        if (!dictDAL.ContainsKey(objType3.FullName))
            //        {
            //            dictDAL.Add(objType3.FullName, objType3);
            //        }
            //    }
            //}


            ////根据注册的接口和接口实现集合，使用IOC容器进行注册
            //foreach (string key in dictInterface.Keys)
            //{
            //    Type interfaceType = dictInterface[key];
            //    foreach (string dalKey in dictDAL.Keys)
            //    {
            //        Type dalType = dictDAL[dalKey];
            //        if (interfaceType.IsAssignableFrom(dalType))//判断DAL是否实现了某接口
            //        {
            //            container.RegisterType(interfaceType, dalType);
            //        }
            //    }
            //}

            ////Type objType = assm.GetType(...)
            ////IInterface objInstance = (IInterface)Activator.CreateInstance(...)
            ////objInstance.DoSomething(...)
            ////container.RegisterType();
            ////ILoginInfoServices ILogin = container.Resolve(objServicesType,);
            //container.AddExtension(new Diagnostic());
            //ILoginInfoServices ILogin= container.Resolve<ILoginInfoServices> ();
            #endregion

           //关于 反射+untiy 实现依赖注入,我失败了... 不知道如何将整个DLL进行注入


            string[] Names = new string[] { "Cgrain", "Whatarey" };
            string[] Nicks = new string[] { "陈粒粒粒粒", "粒粒皆辛苦" };



            // bool texts=await   ILogin.DeleteList<LoginInfoModel>(new int[] { 1, 2, 3 });
            // Console.WriteLine("删除一条数据"); 
            bool isok;//= await ILogin.Delete(maxid);//删除一条
                      //Console.WriteLine(isok ? "删除成功" : "删除失败");

            #region Console.WriteLine("删除全部数据");
            //int iii = await ILogin.Execute(" DELETE  dbo.Login ", null); //sql 删除
            //Console.WriteLine($"删除{iii}行");
            #endregion

            #region 插入
            Console.WriteLine("计算时间:");
            var starttime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss yyy");
            Console.WriteLine(starttime);
            /* 循环插入1000条数据 */
            for (int i = 0; i < 2; i++)
            {
                Console.WriteLine($"添加第{i + 1}行数据");
                LoginInfoModel loginInfoModel = new LoginInfoModel()
                {

                    UserName = Names[i % 2] + i,
                    UserNick = Nicks[i % 2] + i,
                    UserPwd = Guid.NewGuid().ToString("N")
                };

                isok = await ILogin.Insert(loginInfoModel);
                Console.WriteLine($"{i + 1} 行数据 添加{(isok ? "添加成功" : "添加失败")}");
            }
            var endtime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss yyy");
            Console.WriteLine(endtime); 
            Console.WriteLine($"耗时间:{starttime}");
            #endregion
            #region 查询所有
            Console.WriteLine("--查询所有--");
            var LoginInfolist = await ILogin.GetList();
            #endregion

            #region 单条查询
            var maxid = await ILogin.GetMaxId("Login");
            Console.WriteLine($"共有{LoginInfolist.Count()}注册用户");
            var userlist = await ILogin.Get(maxid);
            Console.WriteLine($"查询出来的是:{userlist.UserName},昵称是{userlist.UserNick}");
            #endregion

            #region  事务 异步
            Console.WriteLine("----------异步开始---------------"); 
            string asyncsql = string.Format(@"  
                 DELETE  dbo.Login;  
                insert   login  values(@UserName,@UserNick,@UserPwd); 
                                       ");
            List<LoginInfoModel> loginInfos = new List<LoginInfoModel>();
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine($"添加第{i + 1}行数据");
                LoginInfoModel loginInfoModel = new LoginInfoModel()
                {

                    UserName = Names[i % 2] + i,
                    UserNick = Nicks[i % 2] + i,
                    UserPwd = Guid.NewGuid().ToString("N")
                };
                loginInfos.Add(loginInfoModel);
            }
            var asynccount = await ILogin.ExecuteWithTransactionAsync(asyncsql, loginInfos);
            Console.WriteLine("----------异步结束---------------");
            Console.WriteLine(asynccount > 0 ? "异步事务插入成功" : "异步事务插入失败");

            Console.WriteLine("----------异步开始2---------------");
              asyncsql = string.Format(@"  
                 DELETE  dbo.Login;  
                insert   login  values("","","",""); 
                                       ");  
              asynccount = await ILogin.ExecuteWithTransactionAsync(asyncsql, loginInfos);
            Console.WriteLine("----------异步结束---------------");
            Console.WriteLine(asynccount > 0 ? "异步事务插入成功" : "异步事务插入失败");
            #endregion

            #region  事务同步
            Console.WriteLine("-----------事务同步开始-------------"); 
            string sql = string.Format(@"  insert   login  values(@name,@nick,@pwd);
                                           DELETE  dbo.Login; 
                                           insert   login  values("","","","")
                                       ");

            var count = ILogin.ExecuteWithTransaction(sql,new { name = "jack", nick = "380234234@qq.com", pwd = "上海" });
            Console.WriteLine(count > 0 ? "同步事务成功" : "同步事务失败"); 
            Console.WriteLine($"使用同步事务--执行成功");
            string sql2 = string.Format(@"  insert   login  values(@name,@nick,@pwd)
                                            DELETE  dbo.Login;
                                            insert   login  values(@name,@nick,@pwd)
                                            ");
            var count2 = ILogin.ExecuteWithTransaction(sql2,  new { name = "jack", nick = "380234234@qq.com", pwd = "上海"});
            Console.WriteLine(count2 > 0 ? "同步事务插入成功" : "同步事务插入失败");
            #endregion


            //果然还是要两台电脑..... 

            // 这里有一个问题

            //写到这里,  感觉Dapper 越写越像 ADO.NET
            // 比ADO.NET 调用以及 使用简单了一点, 嗯,以后 可以尝试把面向ADO.NET 的项目升级为 Dapper 
            //关于 Dapper 的使用, 我就写到这里
            // 有添加,删除,修改,查询,事务
            // 你可以用 纯sql+事务的方法进行增删改查
            //也可以用 泛型方法来进行 增删改查
            //我觉得可以两种混用, 或者存储的sql
            //这里 我觉得这个方案挺好的 https://www.cnblogs.com/dudd/p/9778893.html
        }
    }
}
